package com.gitee.wsl.mathematics.geometry.d2.contour.region

import com.gitee.wsl.mathematics.geometry.Interval
import com.gitee.wsl.mathematics.geometry.d2.curve.CurveShape2d
import com.gitee.wsl.mathematics.vector.vec2.Vec2f


internal class Arc(val list:MutableList<CurveShape2d> = mutableListOf()) : MutableList<CurveShape2d> by list {

    private var hashProxy = 0.5f

    private var length = Float.NaN
    private var area = Float.NaN
    fun length(): Float {
        if (length.isNaN()) {
            length = sumOf { c: CurveShape2d ->
                (c.end()-c.start()).length.toDouble()
            }.toFloat()
        }
        return length
    }

    fun signedArea(): Float {
        if (area.isNaN()) {
            area =
                sumOf { obj: CurveShape2d -> obj.signedArea().toDouble() }.toFloat()
        }
        return area
    }

    fun head(): Vec2f {
        return first().start()
    }

    fun tail(): Vec2f {
        return last().end()
    }

    fun position(t: Double): Vec2f {
        val length = length()
        var offset = 0.0
        val threshold = length * t
        for (c in this) {
            val l = (c.end()-c.start()).length
            val i = Interval(offset, offset + l)
            if (i.contains(threshold)) {
                return c.position(i.normalize(threshold))
            }
            offset = i.hi
        }
        throw IllegalStateException()
    }

    fun reverse(): Arc {
        return Arc(reversed().map { it.reverse() }.toMutableList())
    }

    fun vertices(): List<Vec2f> {
        return listOf(head()) + map { it.end()}
    }

    override fun hashCode(): Int {
        return hashProxy.hashCode()
    }

    override fun equals(other: Any?): Boolean {
        return this === other
    }
}

